package com.pointi.emoGatewayM;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.net.Socket;
import java.util.concurrent.ConcurrentLinkedQueue;

import com.pointi.emoTools.emoCheckList;
import com.pointi.emoTools.FileListData;

public class ThreadReceiver extends Thread
{
	//____________________________________________________________________________________________________
	// DEF

	private ConcurrentLinkedQueue<ThreadReceiver> activeThreads ;
	private Socket socket ;
	private ConfigurationData conf_data ;
	private JDBC jdbc ;

	//____________________________________________________________________________________________________
	// INIT

	public ThreadReceiver(ConcurrentLinkedQueue<ThreadReceiver> activeThreads)
	{
		this.activeThreads = activeThreads ;
	}

	public void start(Socket socket, ConfigurationData conf_data, JDBC jdbc)
	{
		activeThreads.add(this) ;
		this.socket = socket ;
		this.conf_data = conf_data ;
		this.jdbc = jdbc ;
		this.fnPrepareDirectory() ;
		super.start();
	}

	private void fnPrepareDirectory()
	{
		File dir = new File(conf_data.s_gateway_org_path) ;
		if (!dir.exists()) { dir.mkdirs() ; }
	}

	//____________________________________________________________________________________________________
	// RUN // Gateway Receiver //

	public void run()
	{
		try {
			/** Open Socket **/
			DataInputStream dis = new DataInputStream(socket.getInputStream()) ;
			DataOutputStream dos = new DataOutputStream(socket.getOutputStream()) ;
			/** Receive **/
			dos.writeBoolean(this.fnReceiveFileList(dis)) ; // 001
			dos.writeBoolean(this.fnReceiveFile(dis)) ; // 002
			/** Close Socket **/
			dis.close() ;
			socket.close() ;
		}
		catch (Exception e) { e.printStackTrace() ; }
		finally { try { socket.close() ; } catch(Exception e) { e.printStackTrace() ; } }
		activeThreads.remove(this) ;
	}

	//____________________________________________________________________________________________________
	// 001 // RECEIVE FILELIST

	private boolean fnReceiveFileList(DataInputStream dis)
	{
		boolean condition = false ;
		try {
			String fileName = dis.readUTF() ;
			int fileLength = Integer.parseInt(dis.readUTF()) ;
			System.out.println("[GW][RCV] FileList Ready : " + fileName + " (" + fileLength + " bytes) ") ;

			byte [] mContainer = null ;
			if (fileLength != 0) {
				int mFrameLength = 100 ;
				int SP = 0 ;
				int EP = fileLength ;
				mContainer = new byte [fileLength] ;
				while(SP < EP) {
					if ((SP + mFrameLength) > EP) mFrameLength = EP - SP ;
					dis.read(mContainer, SP, mFrameLength) ;
					SP += mFrameLength ;
				}
			}
			FileListData fld = new FileListData() ;
			try {
				if (mContainer.length != 0)
					// fld = fld.ReadFileList(mContainer) ;
					fld = fld.fnSetTempData(mContainer, fileName, fileLength, jdbc) ;
			} catch (Exception e) { e.printStackTrace() ; }
			this.fnCreateCallkey(fld) ;
			condition = true ;
		} catch(Exception e) { e.printStackTrace(); }
		return condition ;
	}
	//____________________________________________________________________________________________________
	// 001 // A 
	private void fnCreateCallkey(FileListData fld)
	{
		jdbc.fnPrepareNextDay() ;
		int agentID = jdbc.fnInsertAgentInfo(fld._usr_id, fld._usr_name, fld._usr_ext_no) ;
		int customerID = jdbc.fnInsertCustomerInfo(fld._cust_name, fld._cust_no, fld._cust_tel) ;
		int callKey = jdbc.fnCreateCallKey(fld._call_start_time, agentID, customerID) ;
		jdbc.fnInsertCheckList(callKey) ;
		jdbc.fnInsertFileInfo(callKey, conf_data.s_gateway_org_path, fld._file_name) ;
		System.out.println(String.format("[GW][RCV] Callkey Created (AID : %d | CID : %d | CKEY : %d)", agentID, customerID, callKey)) ;			

	}
	//____________________________________________________________________________________________________
	// 002 // RECEIVE FILE
	private boolean fnReceiveFile(DataInputStream dis)
	{
		boolean condition = false ;
		try {
			String fileName = dis.readUTF() ;
			int fileLength = Integer.parseInt(dis.readUTF()) ;
			System.out.println("[GW][RCV] File Ready : " + fileName + " (" + fileLength + " bytes) ") ;
			int callKey = jdbc.fnGetCallKeyByFileName(fileName) ;

			//BufferedOutputStream bos = null ;
			//FileOutputStream fos = null ;
			byte [] mContainer = null ;
			if (fileLength != 0)
			{
				System.out.println("[GW][RCV] File Receive : " + fileName + " (" + fileLength + " bytes) ") ;
				int mFrameLength = 100 ;
				int SP = 0 ;
				int EP = fileLength ;
				mContainer = new byte [fileLength] ;

				//File mFile = new File(fileTargetPath + fileName) ;
				//fos = new FileOutputStream(mFile) ;
				//bos = new BufferedOutputStream(fos) ;

				jdbc.fnUpdateCheckList(emoCheckList.mCheckReceiver, emoCheckList._START, callKey) ;
				while(SP < EP)
				{
					if (SP == 0) jdbc.fnUpdateCheckList(emoCheckList.mCheckReceiver, emoCheckList._ON, callKey) ;
					if ((SP + mFrameLength) > EP) mFrameLength = EP - SP ;
					dis.read(mContainer, SP, mFrameLength) ; 
					//bos.write(mContainer, SP, mFrameLength) ;
					//bos.flush() ;
					SP += mFrameLength ;
				}
				jdbc.fnUpdateCheckList(emoCheckList.mCheckReceiver, emoCheckList._END, callKey) ;
				//bos.close() ;
				//fos.close() ;
			}
			condition = true ;
		} catch(Exception e) { e.printStackTrace(); }
		return condition ;
	}

	//____________________________________________________________________________________________________
	// EOC
}
